#pragma once

#include <list>

#include "listeners.h"
#include "Passenger.h"
#include "Floor.h"

class CElevator
{
	typedef std::list<CallRequest*> CallRequestRegistry;
public:
	CElevator(const FloorsCollection& inputFloors, size_t capacity);
	~CElevator(void);
private:
	void MoveUp();
	void MoveDown();
	void StartMove();
	void UnloadPassengers();
	void UpdateCalls();

	size_t m_curFloor;
	size_t m_capacity;
	size_t m_steps;
	bool m_upDirection;

	PassengerCollection m_passengers, m_passengerToExit;
	FloorsCollection m_floors;
	CallRequestRegistry m_currentCallRequests, m_incomingCallRequests;

	class CElevatorListener
	{
	protected:
		CElevator& m_elevator;
		CElevatorListener(CElevator& el) : m_elevator(el){}
	};

	struct CPassengerArrivedListener : public IPassengerListener, CElevatorListener
	{
		CPassengerArrivedListener(CElevator& el) : CElevatorListener(el) {};
		virtual void OnPassengerArrived(CPassenger* passenger);
	};

	struct CIncomingPassengersListener : public ILoadPassengersListener, CElevatorListener
	{
		CIncomingPassengersListener(CElevator& el) : CElevatorListener(el) {};
		virtual void LoadPassengersAtArival(PassengerCollection& incomingPassengers);
	};

	struct CallRequestlistener : public ICallRequestListener, CElevatorListener
	{
		CallRequestlistener(CElevator& el) : CElevatorListener(el) {};
		virtual void OnCallRequest(CallRequest* request);
	};
};

